package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.article.IArticleClient;
import com.heima.audit.aliyun.GreenImageScan;
import com.heima.audit.aliyun.GreenTextScan;
import com.heima.audit.tess4j.Tess4jClient;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.constants.WmNewsMessageConstants;
import com.heima.common.redis.CacheService;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.NewsAuthDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.*;
import com.heima.model.wemedia.vo.WmNewsVo;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.common.ThreadLocalUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author itheima
 */
@Slf4j
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    WmMaterialService wmMaterialService;

    @Autowired
    WmNewsMaterialService wmNewsMaterialService;


//    @Autowired
//    private GreenTextScan greenTextScan;
//
//    @Autowired
//    private FileStorageService fileStorageService;
//
//    @Autowired
//    private GreenImageScan greenImageScan;
//
//    @Autowired
//    private IArticleClient articleClient;
//
//    @Autowired
//    private WmUserService wmUserService;
//
//    @Autowired
//    private WmChannelService wmChannelService;

    @Autowired
    ExecutorService executorService;

//    @Autowired
//    WmSensitiveMapper wmSensitiveMapper;
//
//    @Autowired
//    Tess4jClient tess4jClient;

    @Autowired
    WmNewsTaskService wmNewsTaskService;
    @Autowired
    WmUserService wmUserService;

    @Override
    public ResponseResult submitNews(WmNewsDto dto) {
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        wmNews.setUserId(ThreadLocalUtil.getUserId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        if(dto.getImages()!=null&&!dto.getImages().isEmpty()){
            //[a.png b.png]->a.png,b.png
            String imageJoin = StringUtils.join(dto.getImages(), ",");
            wmNews.setImages(imageJoin);
        }
        this.save(wmNews);

        //第二步 关联文章内容和素材关系
        String content = dto.getContent();
        StringBuffer contentBuffer =new StringBuffer(dto.getTitle()); //文章要审计的内容
        //提取文章素材
        List<String> contentImages= new ArrayList<>();
        JSONArray jsonArray = JSON.parseArray(content);
        for (Object o : jsonArray) {
            JSONObject jsonObject = (JSONObject) o;
            if(jsonObject.get("type").equals("image")){
                contentImages.add(jsonObject.get("value").toString());
            }else{
               //文章内容
                contentBuffer.append(jsonObject.get("value").toString());
            }
        }
        //建立素材库多对多关系
        addWmNewsMaterial(wmNews, contentImages, WemediaConstants.WM_CONTENT_REFERENCE);

        //建立封面和素材关系
        addWmNewsMaterial(wmNews, dto.getImages(), WemediaConstants.WM_COVER_REFERENCE);

        if(dto.getType()==-1){
            System.out.println("自动匹配");
           //从内容里面提取
            //无图
            if(contentImages.isEmpty()){
                wmNews.setType(WemediaConstants.WM_NEWS_NONE_IMAGE);
                updateById(wmNews);
            }else if(contentImages.size()<3){
                wmNews.setType(WemediaConstants.WM_NEWS_SINGLE_IMAGE);
                //提取第一张
                String one = contentImages.get(0);
                wmNews.setImages(one);
                updateById(wmNews);
                List<String> list = new ArrayList<>();
                list.add(one);
                addWmNewsMaterial(wmNews, list, WemediaConstants.WM_COVER_REFERENCE);

            }else if(contentImages.size()>=3){
                //提取前三张
                List<String> three = contentImages.stream().limit(3).collect(Collectors.toList());
                //[a.png b.png]->a.png,b.png
                String imageJoin = StringUtils.join(three, ",");
                wmNews.setImages(imageJoin);
                wmNews.setType(WemediaConstants.WM_NEWS_MANY_IMAGE);
                updateById(wmNews);
                addWmNewsMaterial(wmNews, three, WemediaConstants.WM_COVER_REFERENCE);
            }
        }

        //审核 同步 异步
        //内容审核 发布
        wmNewsTaskService.addNewsToTask(wmNews);
//        executorService.submit(new Runnable() {
//            @Override
//            public void run() {

//              boolean  contentAuditResult =true;
//               // boolean contentAuditResult = contentAudit(wmNews, contentBuffer.toString());
//                if(contentAuditResult){
//                    //图片审核
//                    Set<String> imagesAudit =new HashSet<>();
//                    if(!contentImages.isEmpty()){
//                        imagesAudit.addAll(contentImages);
//                    }
//
//                    if(dto.getImages()!=null&&!dto.getImages().isEmpty()){
//                        imagesAudit.addAll(dto.getImages());
//                    }
//                    //自动图片来源文章
//
//                    //boolean imageAuditResult = imageAudit(wmNews, imagesAudit);
//                    boolean imageAuditResult =true;
//                    if(imageAuditResult){
//                        //发起feign数据同步
//                        ArticleDto articleDto = new ArticleDto();
//                        BeanUtils.copyProperties(wmNews,articleDto);
//                        articleDto.setContent(dto.getContent());
//                        articleDto.setAuthorId(Long.valueOf(wmNews.getUserId()));
//                        articleDto.setLayout(Short.valueOf(""+wmNews.getType()));
//                        WmUser user= wmUserService.getById(wmNews.getUserId());
//                        articleDto.setAuthorName(user.getName());
//                        WmChannel channel = wmChannelService.getById(dto.getChannelId());
//                        articleDto.setChannelName(channel.getName());
//                        ResponseResult responseResult = articleClient.saveArticle(articleDto);
//                        if(responseResult.getCode()==AppHttpCodeEnum.SUCCESS.getCode()){
//                            Long articleId = Long.valueOf(""+responseResult.getData());
//                            wmNews.setArticleId(articleId);
//                            updateWmNews(wmNews, WmNews.Status.PUBLISHED, "发送成功");
//                        }else{
//                            updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH, "转人工");
//                        }
//                    }
//                }
//            }
//        });
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



//    @Autowired
//    private  CacheService cacheService;
//
//    private boolean dfaSensitives(WmNews wmNews,String content){
//        //自定义敏感词过滤 dfa算法
//        //先读取缓存，如果换成没有，再读取数据库，把数据库数据放入缓存
//        Set<String> sensitivesSet = cacheService.setMembers(WemediaConstants.CACHE_KEY_SECSITIVE);
//        //List<String> sensitivesList;
//        if(sensitivesSet.isEmpty()){
//            List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(null);
//            List<String>  sensitivesList = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
//            if(!sensitivesList.isEmpty()){
//                for (String sensitive : sensitivesList) {
//                    cacheService.sAdd(WemediaConstants.CACHE_KEY_SECSITIVE,sensitive);
//                }
//            }
//            sensitivesSet = cacheService.setMembers(WemediaConstants.CACHE_KEY_SECSITIVE);
//        }
//        if(!sensitivesSet.isEmpty()){
//            SensitiveWordUtil.initMap(sensitivesSet);
//            Map<String, Integer> result = SensitiveWordUtil.matchWords(content);
//            if(!result.isEmpty()){
//                updateWmNews(wmNews, WmNews.Status.FAIL, "包含敏感词，审核失败");
//                return false;
//            }
//        }
//        return true;
//    }
//
//    private boolean contentAudit(WmNews wmNews,String content){
//        try {
//            //自定义敏感词过滤 dfa算法
//              boolean sensitivesExit = dfaSensitives(wmNews, content);
//               //fase 存在
//               if(!sensitivesExit){
//                return false;
//               }
//                Map greeTextScan = greenTextScan.greeTextScan(content);
//                String suggestion =String.valueOf(greeTextScan.get("suggestion"));
//                if(StringUtils.isNotBlank(suggestion)){
//                    //block 文字有敏感词
//                    if("block".equals(suggestion)){
//                        updateWmNews(wmNews, WmNews.Status.FAIL, "包含敏感词，审核失败");
//                        return false;
//                    }
//                    //review
//                    if("review".equals(suggestion)){
//                        updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH, "需要人工审核");
//                        return false;
//                    }
//                }
//
//        } catch (Exception e) {
//            // e.printStackTrace();
//            return false;
//        }
//
//        return true;
//    }
//
//    private boolean imageAudit(WmNews wmNews, Set<String> imageList){
//        try {
//            if(!imageList.isEmpty()){
//                List<byte []> list = new ArrayList<>();
//                for (String url : imageList) {
//                    byte[] bytes = fileStorageService.downLoadFile(url);
//                    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
//                    BufferedImage imageFile = ImageIO.read(in);
//                    String result = tess4jClient.doOCR(imageFile);
//                    boolean sensitivesNotExit = dfaSensitives(wmNews, result);
//                    //fasle 检验出来
//                    if(!sensitivesNotExit){
//                        return false;
//                    }
//                    list.add(bytes);
//                }
//
//                Map greeTextScan = greenImageScan.imageScan(list);
//                String suggestion =String.valueOf(greeTextScan.get("suggestion"));
//                if(StringUtils.isNotBlank(suggestion)){
//                    //block 文字有敏感词
//                    if("block".equals(suggestion)){
//                        updateWmNews(wmNews, WmNews.Status.FAIL, "图片审核失败");
//                        return false;
//                    }
//                    //review
//                    if("review".equals(suggestion)){
//                        updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH, "需要人工审核");
//                        return false;
//                    }
//                }
//            }
//        } catch (Exception e) {
//            // e.printStackTrace();
//            return false;
//        }
//
//        return true;
//    }
//
//    private void updateWmNews(WmNews wmNews, WmNews.Status fail, String s) {
//        wmNews.setStatus(fail.getCode());
//        wmNews.setReason(s);
//        updateById(wmNews);
//    }


    private void addWmNewsMaterial(WmNews wmNews, List<String> contentImages,int type) {
        if(!contentImages.isEmpty()){
            //根据urls 找相关ids  select * from wm_material where url in()
            LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(WmMaterial::getUrl,contentImages);
            List<WmMaterial> wmMaterialList = wmMaterialService.list(queryWrapper);
            if(!wmMaterialList.isEmpty()){
                //ids jdk18
                List<WmNewsMaterial> list =new ArrayList();
                List<Integer> idList = wmMaterialList.stream().map(WmMaterial::getId).collect(Collectors.toList());
                int order=0;
                for (Integer id : idList) {
                    WmNewsMaterial wmNewsMaterial =new WmNewsMaterial();
                    wmNewsMaterial.setMaterialId(id);
                    wmNewsMaterial.setNewsId(wmNews.getId());
                    wmNewsMaterial.setType(type);
                    wmNewsMaterial.setOrd(order++);
                    list.add(wmNewsMaterial);
                }
                wmNewsMaterialService.saveBatch(list);
            }
        }
    }


    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {

        Page<WmNews> page = new Page<>();
        page.setCurrent(dto.getPage());
        page.setSize(dto.getSize());

        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(WmNews::getUserId, ThreadLocalUtil.getUserId());

        if(StringUtils.isNotBlank(dto.getKeyword())){
            queryWrapper.like(WmNews::getTitle,dto.getKeyword());
        }
        if(dto.getStatus()!=null){
            queryWrapper.eq(WmNews::getStatus,dto.getStatus());
        }
        if(dto.getBeginPubDate()!=null&&dto.getEndPubDate()!=null){
            queryWrapper.between(WmNews::getPublishTime,dto.getBeginPubDate(),dto.getEndPubDate());
        }

        if(dto.getChannelId()!=null){
            queryWrapper.eq(WmNews::getChannelId,dto.getChannelId());
        }

        queryWrapper.orderByDesc(WmNews::getCreatedTime);
        page = this.page(page, queryWrapper);
        PageResponseResult pageResponseResult =new PageResponseResult(page);
        pageResponseResult.setCode(AppHttpCodeEnum.SUCCESS.getCode());
        pageResponseResult.setErrorMessage(AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return pageResponseResult;
    }


    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        WmNews wmNews = this.getById(dto.getId());
        wmNews.setEnable(Short.valueOf(""+dto.getEnable()));
        this.updateById(wmNews);
        Map<String,Object> map= new HashMap<>();
        map.put("articleId",wmNews.getArticleId());
        boolean isDown =false;
        if(dto.getEnable()==0){
            isDown =true;
        }
        map.put("isDown",isDown);
        kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(map));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult listVo(NewsAuthDto dto) {
        //分页构造器
        Page<WmNews> page = new Page<>();
        page.setSize(dto.getSize());
        page.setCurrent(dto.getPage());



        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        //模糊查询
        if(StringUtils.isNotBlank(dto.getTitle())){
            queryWrapper.like(WmNews::getTitle,dto.getTitle());
        }

        //根据审核状态精确查询
        if (dto.getStatus() != null) {
            queryWrapper.eq(WmNews::getStatus,dto.getStatus());
        }

        //根据创建时间倒叙
        queryWrapper.orderByDesc(WmNews::getCreatedTime);

        page = this.page(page, queryWrapper);

        Page<WmNewsVo> wmNewsVoPage = new Page<>();
        BeanUtils.copyProperties(page,wmNewsVoPage,"records");
        List<WmNewsVo> wmNewsVoList = page.getRecords().stream().map(wmNews -> {
            WmNewsVo wmNewsVo = new WmNewsVo();
            BeanUtils.copyProperties(wmNews, wmNewsVo);
            WmUser wmUser = wmUserService.getById(wmNews.getUserId());
            String authorName = wmUser.getName();
            wmNewsVo.setAuthorName(authorName);
            return wmNewsVo;

        }).collect(Collectors.toList());

        wmNewsVoPage.setRecords(wmNewsVoList);


        PageResponseResult pageResponseResult = new PageResponseResult(wmNewsVoPage);
        pageResponseResult.setCode(AppHttpCodeEnum.SUCCESS.getCode());
        pageResponseResult.setErrorMessage(AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return pageResponseResult;
    }

    @Override
    public ResponseResult findDetails(Integer id) {

      /*  WmNews wmNewsInDb = this.getById(id);
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNewsInDb, wmNewsVo);
        String name = this.wmUserService.getById(wmNewsVo.getUserId()).getName();
        wmNewsVo.setAuthorName(name);

        return ResponseResult.okResult(wmNewsVo);*/
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmNews::getId,id);
        WmNews wmNews = this.getOne(queryWrapper);
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        String name=wmUser.getName();
        wmNewsVo.setAuthorName(name);
        return  ResponseResult.okResult(wmNewsVo);


    }

    @Override
    public ResponseResult isNot(NewsAuthDto dto) {
        WmNews wmNewsInDb=this.getById(dto.getId());
        wmNewsInDb.setStatus(WmNews.Status.FAIL.getCode());
        wmNewsInDb.setReason(dto.getMsg());
        this.updateById(wmNewsInDb);
        return ResponseResult.okResult("操作成功");
    }


    @Override
    public ResponseResult isYes(NewsAuthDto dto) {
        WmNews wmNewsInDb=this.getById(dto.getId());
        wmNewsInDb.setStatus(WmNews.Status.ADMIN_SUCCESS.getCode());
        wmNewsInDb.setReason(dto.getMsg());
        this.updateById(wmNewsInDb);
        wmNewsTaskService.addNewsToTask(wmNewsInDb);

        return ResponseResult.okResult("操作成功");
    }
}
